 /**    
  *******************************************************************************************************   
  * @attention    
  * Copyright (c) 2023, SHANGHAI FUDAN MICROELECTRONICS GROUP CO., LTD.(FUDAN MICROELECTRONICS./ FUDAN MICRO.)    
  * All rights reserved.    
  *    
  * Processor:                   FM33FG0xxA    
  * http:                        http://www.fmdevelopers.com.cn/    
  *    
  * Redistribution and use in source and binary forms, with or without    
  * modification, are permitted provided that the following conditions are met    
  *    
  * 1. Redistributions of source code must retain the above copyright notice,    
  *    this list of conditions and the following disclaimer.    
  *    
  * 2. Redistributions in binary form must reproduce the above copyright notice,    
  *    this list of conditions and the following disclaimer in the documentation    
  *    and/or other materials provided with the distribution.    
  *    
  * 3. Neither the name of the copyright holder nor the names of its contributors    
  *    may be used to endorse or promote products derived from this software    
  *    without specific prior written permission.    
  *    
  * 4. To provide the most up-to-date information, the revision of our documents     
  *    on the World Wide Web will be the most Current. Your printed copy may be      
  *    an earlier revision. To verify you have the latest information avaliable,    
  *    refer to: http://www.fmdevelopers.com.cn/.    
  *    
  * THIS SOFTWARE IS PROVIDED BY FUDAN MICRO "AS IS" AND ANY EXPRESSED:     
  * ORIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES     
  * OF MERCHANTABILITY NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE    
  * ARE DISCLAIMED.IN NO EVENT SHALL FUDAN MICRO OR ITS CONTRIBUTORS BE LIABLE     
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL     
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS     
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER    
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,     
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY WAY OUT OF THE     
  * USE OF THIS SOFTWARE, EVEN IF ADVISED OFTHE POSSIBILITY OF SUCH DAMAGE.  
  *
  ******************************************************************************************************* 
  */     
#include "main.h"
#include "fm33fg0xxa_fl.h"
#include "iwdt.h"
#include "svd.h"
#include "rmu.h"
#include "canfd.h"
#include "pll.h"
#include "gptim.h"

#include "IF_GpioAbst.h"
#include "IF_Switch.h"


uint32_t TEST_CAN_CommunicationReady = 0;

/**
  * @brief  ECC检错中断不可屏蔽，直接进入NMI中断服务 请保留 
  * @param  None
  * @retval None
  */
void NMI_Handler(void)
{
    uint32_t RAMDetectionFlag = 0, DataFlashDetectionFlag = 0, CodeFlashDetectionFlag = 0;
    uint32_t WakeUpDebugFlag = 0;
    
    /* RAM ECC 检错 必须保留 */
    RAMDetectionFlag = FL_FLASH_IsActiveFlag_ECCDetectionInRAM(FLASH);
    if (0x01U == RAMDetectionFlag)
    {   
        FL_FLASH_ClearFlag_ECCDetectionInRAM(FLASH);
        /* 客户安全处理 */
        /* ...... */
    }
    
    /* Data Flash ECC检错 必须保留 */ 
    DataFlashDetectionFlag = FL_FLASH_IsActiveFlag_ECCDetectionInDataFlash(FLASH);
    if (0x01U == DataFlashDetectionFlag)
    {
        FL_FLASH_ClearFlag_ECCDetectionInDataFlash(FLASH); 
        /* 客户安全处理 */
        /* ...... */
    }
    
    /* Code Flash ECC检错 必须保留 */ 
    CodeFlashDetectionFlag = FL_FLASH_IsActiveFlag_ECCDetectionInCodeFlash(FLASH);
    if (0x01U == CodeFlashDetectionFlag)
    {
        FL_FLASH_ClearFlag_ECCDetectionInCodeFlash(FLASH); 
        /* 客户安全处理 */
        /* ...... */
    }
    
    /* CPU Debugger唤醒 必须保留 */
    WakeUpDebugFlag = FL_PMU_IsActiveFlag_WakeupDBG(PMU);
    if (0x01U == WakeUpDebugFlag)
    {
        FL_PMU_ClearFlag_WakeupDBG(PMU);
    }
}

/**
  * @brief  HardFault 中断服务函数 请保留 
  * @param  None
  * @retval None
  */
void HardFault_Handler(void)
{   /* 软件复位MCU，使用内联函数 */
    RMU_Soft_SystemReset();
}

/**
  * @brief  掉电监控，用于执行掉电事件
  * @param  None
  * @retval None
  */
static void PowerDownMonitoring(void)
{
    /* 确认SVD监测结果是否低于阈值 */
    if (true == SVD_Result_Confirmed(SVD_BELOW_THRESHOLD, 1U))
    {   /* 防抖处理 */
        if (true == SVD_Result_Confirmed(SVD_BELOW_THRESHOLD, 2000U/*us*/))
        {
            /* 电压下降到报警阈值，处理掉电事件 */
            /* 用户程序1 */
            /* ...... */
            /* 注意：用户需确保在BOR复位之前执行完毕 */
            
            /* 确认SVD监测结果是否高于阈值，如否则持续等待 */
            while(false == SVD_Result_Confirmed(SVD_HIGHER_THRESHOLD, 20U/*us*/));
            /* 由于电源有下降到报警阈值，软件复位后重新初始化 */
            RMU_Soft_SystemReset();
        }
    }
}
void IF_SleepMngTask_10ms(void);
int main(void)
{
    uint32_t i;
    unsigned char sysCycleMs = 0;
    
    /* 使能IWDT */
    (void)IWDT_Init(FL_IWDT_PERIOD_4000MS);
    
    /* 延时函数初始化 */
    FL_Init();
    
    /* 使能SVD,阈值4.16V(falling)~4.284V(rising) */
    (void)SVD_Init(SVD_MONTIOR_VDD,FL_SVD_WARNING_THRESHOLD_GROUP11,FL_SVD_REFERENCE_1P0V);
    
    /* 确认SVD监测结果是否高于阈值，如否则持续等待 */
    while(false == SVD_Result_Confirmed(SVD_HIGHER_THRESHOLD, 2000U/*us*/));
    
    /* 使能BOR为2.0V */
    RMU_BOR_Init(FL_RMU_BOR_THRESHOLD_2P00V);

    /* 休眠下冻结看门狗计数 */
    IWDT_SLP_Freeze(FL_ENABLE);
    
    /* 先将外部XTHF分频到1M，再利用PLL锁相环倍频至32M，具体请见初始化参数 */
    (void)SelXTHFToPLL(&CMU_XTHF_Init_Data, &CMU_PLL_Init_Data);
    
    /* 用于监控XTHF停振事件和PLL失锁事件，先配置系统时钟，再使能该监控定时器, 10ms周期 */
    GPTIM_Init();//LPTIM16_Init();

    IF_GpioAbst_Init();
    IF_GpioAbs_HallPwrCtrl(ON);
    IF_GpioAbs_UbdPwrAdcDetCtrl(ON);
    IF_GpioAbs_CanPwrCtrl(ON);
    /* CANFD外设初始化 */
    (void)Can_Init(CANFD1);
    /* CANFD外设初始化后，在检测到总线连续11bit隐性位时CANFD外设才正式通信准备完毕，并可以执行通信 */
    /* 查询CANFD外设通信准备完毕标志，由于总线是受外部影响的，用户程序应考虑总线被一直拉低或长时间拉低的冗余处理 */
    for (i = 0; i < 1000; i++)
    {
        if (FL_CANFD_CH0_IsActiveFlag_CommStatus(CANFD1))
        {
            TEST_CAN_CommunicationReady = 0x55;
            break;
        }
    }
    // FL_DelayMsStart(1);
    IF_Switch_Init();
    CRC_Init();

    while(1)
    {
        if (1 == Period10msFlag)// if(FL_DelayEnd())//1ms
        {
            Period10msFlag = 0;
            sysCycleMs++;
            /* 清狗 */
            IWDT_Clr();
            
            if(sysCycleMs % 10 == 3)
            {          
                IF_SwitchScanTask_10ms();
                /* 电源掉电监测处理 */
                PowerDownMonitoring();
                /* 判断是否发生XTHF停振或PLL失锁事件，如有及时切回主系统时钟 */
                SwtichToMainSystemClock(&CMU_RCHF_Init_Data, &CMU_XTHF_Init_Data, &CMU_PLL_Init_Data);
                if (0x55 != TEST_CAN_CommunicationReady)
                {
                    /* 受总线影响，初始化后未查询到CANFD通讯准备完毕标志，此处继续查询 */
                    /* 由于总线是受外部影响的，用户程序应考虑总线被一直拉低或长时间拉低的冗余处理 */
                    if (FL_CANFD_CH0_IsActiveFlag_CommStatus(CANFD1))
                    {
                        TEST_CAN_CommunicationReady = 0x55;
                    }
                }
                IF_SleepMngTask_10ms();//Sleep_Wakeup();
            }
            if(sysCycleMs % 20 == 5)
            {
                
            }
            if(sysCycleMs == 100)
            {
                uint16_t crx166;
                sysCycleMs = 0;
                crx166 = CRC16_CCITT_Cal();
                /* 功能执行 */
                /* CANFD外设已通讯准备完毕，执行帧发送任务 */
                if (0x55 == TEST_CAN_CommunicationReady)
                {                
                    /* 填充发送数据 */
                    CAN_SetMsg(&TxMessage);
                    
                    /* 执行数据发送 */
                    TransmitMsg_0x308();// FL_CAN_Frame_Send(FL_CANFD_FORMAT_FD_STANDARD_DATA, BRS_ENABLE, &TxMessage, TEST_CAN);
                }
            }
            
        }
    }
}


